﻿using System;
using System.Collections.Generic;
using System.Linq;
using Stamp_For_Africa_Version_2.Models;

namespace Stamp_For_Africa_Version_2.Repositories
{
	public class CollectionRepository
	{
		private readonly StampsDataContext _dataContext = new StampsDataContext();

		public IQueryable<Collection> FindAllCollections()
		{
			return _dataContext.Collections;
		}

		public Collection GetCollection(Guid id)
		{
			return _dataContext.Collections.SingleOrDefault(d => d.Id == id);
		}

		public IQueryable<Collection> GetMyCollection(Guid userId)
    {
			return _dataContext.Collections.Where(u => u.UserId == userId);
    }
		public IQueryable<Collection> GetMyMintCollection(Guid userId)
    {
			return _dataContext.Collections.Where(u => u.UserId == userId && u.State == Collection.StampState.MintNeverHinged);
    }
		public IQueryable<Collection> GetMyMintHingedCollection(Guid userId)
    {
			return _dataContext.Collections.Where(u => u.UserId == userId && u.State == Collection.StampState.MintHinged);
    }
		public IQueryable<Collection> GetMyUsedCollection(Guid userId)
    {
			return _dataContext.Collections.Where(u => u.UserId == userId && u.State == Collection.StampState.Used);
    }

		public Collection GetCollectionForStamp(Guid stampId)
		{
			return _dataContext.Collections.SingleOrDefault(d => d.StampId == stampId);
		}

		public int AddStampToCollection(Guid userId, Guid stampId, int quantity, Collection.StampState stampState)
    {
			Collection collection =
				_dataContext.Collections.Where(u => u.UserId == userId && u.StampId == stampId && u.State == stampState).
          FirstOrDefault();

			if (collection == null)
      {
				collection = new Collection();
				collection.UserId = userId;
				collection.Id = Guid.NewGuid();
				collection.Quantity = quantity;
				collection.StampId = stampId;
				collection.State = stampState;
				_dataContext.Collections.InsertOnSubmit(collection);
      }
      else
      {
				collection.Quantity += quantity;

      }
			return collection.Quantity;
      
    }

    public int AddStampToCollection(Guid userId, Guid stampId, String mintNh, String mintH, String used)
    {

    	int iMintNh = 0;
			if (!String.IsNullOrEmpty(mintNh))
				iMintNh = int.Parse(mintNh);

    	int iMintH = 0;
			if (!String.IsNullOrEmpty(mintH))
				iMintH = int.Parse(mintH);

    	int iUsed = 0;
			if (!String.IsNullOrEmpty(used))
				iUsed = int.Parse(used);

      if (iMintNh > 0)
				AddStampToCollection(userId, stampId, iMintNh, Collection.StampState.MintNeverHinged);

			if (iMintH > 0)
				AddStampToCollection(userId, stampId, iMintH, Collection.StampState.MintHinged);

			if (iUsed > 0)
				AddStampToCollection(userId, stampId, iUsed, Collection.StampState.Used);
     

      Save();
      return 0;
    }

		public int RemoveStampsFromCollection(Guid userId, Guid stampId, String mintNh, String mintH, String used)
		{

			int iMintNh = 0;
			if (!String.IsNullOrEmpty(mintNh))
				iMintNh = int.Parse(mintNh);

			int iMintH = 0;
			if (!String.IsNullOrEmpty(mintH))
				iMintH = int.Parse(mintH);

			int iUsed = 0;
			if (!String.IsNullOrEmpty(used))
				iUsed = int.Parse(used);

			if (iMintNh > 0)
				RemoveStampFromCollection(userId, stampId, iMintNh, Collection.StampState.MintNeverHinged);

			if (iMintH > 0)
				RemoveStampFromCollection(userId, stampId, iMintH, Collection.StampState.MintHinged);

			if (iUsed > 0)
				RemoveStampFromCollection(userId, stampId, iUsed, Collection.StampState.Used);


			Save();
			return 0;
		}

		public void RemoveAllCollectionsWithStampId(Guid userId, Guid stampId)
		{
			IQueryable<Collection> collectionsToDelete = _dataContext.Collections.Where(u => u.UserId == userId && u.StampId == stampId);
			_dataContext.Collections.DeleteAllOnSubmit(collectionsToDelete);
			Save();
		}

		public int RemoveStampFromCollection(Guid userId, Guid stampId, int quantity, Collection.StampState stampState)
		{
			Collection collection =
				_dataContext.Collections.Where(u => u.UserId == userId && u.StampId == stampId && u.State == stampState).
					FirstOrDefault();

			if (collection == null)
			{
				return 0;
			}
			else
			{
				collection.Quantity -= quantity;
				if (collection.Quantity <= 0)
				{
					Delete(collection);
				}
			}
			return 0;

		}

		//
		// Insert/Delete Methods

		public void Add(Collection collection)
		{
			_dataContext.Collections.InsertOnSubmit(collection);
		}

		public void Delete(Collection collection)
		{
			_dataContext.Collections.DeleteOnSubmit(collection);
		}
		
		public int GetStampCount(Guid userId, Guid stampId, int state)
		{
			if (_dataContext.Collections.Where(u => u.UserId == userId && u.StampId == stampId && (int)u.State == state).Count() > 0)
			{
				return
					_dataContext.Collections.Where(u => u.UserId == userId && u.StampId == stampId && (int)u.State == state).Single().
						Quantity;
			}
			return 0;
		}

    public IQueryable<Stamp> GetMyStampCollection(Guid userId)
    {
      List<Guid> myStamps =
				_dataContext.Collections.Where(u => u.UserId == userId).Select(u => u.StampId).Distinct().ToList();
      return _dataContext.Stamps.Where(u => myStamps.Contains(u.Id));
    }

		//
		// Persistence

		public void Save()
		{
			_dataContext.SubmitChanges();
		}
	}
}